home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
001-100
/
001-025
/
001
/
latffp
/
latffp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-17
|
22KB
|
770 lines
/*
* Article 633 of net.micro.amiga:
* ion: version B 2.10.2 9/17/84 chuqui version 1.9 3/12/85; site unisoft.UUCP
* Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site amiga.amiga.UUCP
* Path: unisoft!dual!lll-crg!ucdavis!ucbvax!decvax!decwrl!pyramid!amiga!bobp
* From: bobp@amiga.UUCP (Robert S. Pariseau)
* Newsgroups: net.micro.amiga
* Subject: LatFFP program SOURCE (LONG!)
* Message-ID: <192@amiga.amiga.UUCP>
* Date: 6 Nov 85 03:53:01 GMT
* Date-Received: 17 Nov 85 21:40:30 GMT
* Reply-To: bobp@snake.UUCP (Robert S. Pariseau)
* Organization: Commodore-Amiga Inc., 983 University Ave #D, Los Gatos CA 95030
* Lines: 749
*
* TITLE: LatFFP program SOURCE (LONG!)
*
* The program below shows how to access the Motorola Fast Floating Point
* libraries from V1.0 release Lattice C for the Amiga. As you will see
* when you run it, the performance improvement gained by using the
* FFP routines (even in this kludgey fashion) is generally around a
* factor of 10!
*
* Part of that improvement is just the difference in precision. The
* Lattice stuff provides a 64 bit software implementation of the IEEE
* format. The FFP stuff provides a 32 bit implementation of the
* Motorola format.
*
* The variables used for FFP math are defined as ints. You can't use
* FLOATs because V1.0 Lattice C converts FLOAT to DOUBLE during
* expression evaluation and when passing arguments.
*
*/
/*
* ------------------------Program Notes:
*
* The program will compile and link cleanly using the stuff on the
* standard V1.0 Lattice C for Amiga disk. The Make script in the
* examples directory will do all the work for you. Since my C disk
* is rather full, and since I like the dramatic increase in speed,
* I usually do my work in ram disk as follows:
*
* 1> cd df1: [my C disk]
* 1> copy examples/Make to : [more convenient in root]
*
* 1> copy LatFFP.c to ram:
* 1> execute Make ram:LatFFP
* 1> copy ram:LatFFP to df1:
*
* I've also added a "stack 20000" command in my startup script
* (s/startup-sequence) to make sure I don't have to worry about stack
* overflows.
*
* The program shows 3 bugs in the V1.0 stuff and includes one kludge.
* The bugs and kludge are maked in the source. Bug (1): V1.0 Lattice
* C doesn't properly handle successive assignments of constants. Use
* expressions. Bug (2): V1.0 FFP doesn't correctly return a result
* from SPCmp(). Fake it with subtraction and SPTst() or write your
* own compare for now. Bug (3): V1.0 FFP doesn't correctly return
* the cosine result from SPSincos(). Use SPCos() instead.
*
* The kludge is the set of union definitions so that we can use the
* same variables for related Lattice and FFP expressions and for
* the conversions in and out of IEEE format. Note that we use
* the Lattice IEEE based routines in printf() to get our output.
*
* Note however, that the conversion routines are in the RAM based
* MathTrans library. Therefore, if you only want to use the WCS
* based MathFFP library, you are on your own for conversion.
*
*------------------------Program Source Follows:
*
*/
/***********************************************************************
* LatFFP -- Program to show the use of Motorola Fast Floating Point
* math libraries with V1.0 Lattice C for the Amiga in
* comparison to the DOUBLE precision IEEE floating point
* math which is built in to the C. The FFP format is
* a 32 bit format.
*
* Larry Hildenbrand -- Nov. 4, 1985
* Bob Pariseau -- Nov. 4, 1985 (minor editorial corrections)
*
***********************************************************************/
#include <exec/types.h>
#include <math.h>
/* ??? #define E 2.718281828459045 */ /* V1.0 Lattice C BUG! See */
#define PIME 0.423310826 /* below. PIME == PI - E. */
/**** MAY BE BROKEN OUT INTO SEPARATE #include FILE ****/
extern int SPFix();
extern int SPFlt();
extern int SPCmp();
extern int SPTst();
extern int SPAbs();
extern int SPNeg();
extern int SPAdd();
extern int SPSub();
extern int SPMul();
extern int SPDiv();
extern int SPAtan();
extern int SPSin();
extern int SPCos();
extern int SPTan();
extern int SPSincos();
extern int SPSinh();
extern int SPCosh();
extern int SPTanh();
extern int SPExp();
extern int SPLog();
extern int SPPow();
extern int SPSqrt();
extern int SPTieee();
extern int SPFieee();
/********************************************************/
char st1[80] = "3.1415926535897";
char st2[80] = "2.718281828459045";
int MathBase; /* Basic FFP lib pointer */
int MathTransBase; /* Transcendental FFP lib pointer */
int dots_good = 0;
union kludge1 /* Can't use FLOAT directly for FFP stuff */
{ /* because V1.0 Lattice converts FLOAT to */
FLOAT num1; /* DOUBLE in expressions and when passing */
int i1; /* parameters. */
} k1;
union kludge2
{
FLOAT num2;
int i2;
} k2;
union kludge3
{
FLOAT num3;
int i3;
} k3;
union kludge4
{
FLOAT num4;
int i4;
} k4;
union kludge5
{
FLOAT num5;
int i5;
} k5;
union kludge6
{
FLOAT num6;
int i6;
} k6;
show_dot() { if( ++dots_good == 1000) { dots_good = 0; printf(".");} }
show_result( num ) FLOAT num; { printf("\nResult = %f", num); }
show_result_ffp(in_val) /* Convert to IEEE and display */
int in_val;
{
union kludge_sr
{
FLOAT new_iv_f;
int new_iv_i;
} k;
k.new_iv_i = SPTieee(in_val);
show_result(k.new_iv_f);
}
main() /* Lattice/FFP test code */
{
UWORD i;
int i3;
printf("C-ROM & Shared RAM Library Test Facility for the Amiga-Lattice Basic/Trans Math Libraries");
/*****************************************/
/*****************************************/
/*** ***/
/*** OPEN ROM AND RAM FFP LIBRARIES ***/
/*** ***/
/*****************************************/
/*****************************************/
if((MathBase = OpenLibrary("mathffp.library", 0)) < 1 ) {
printf("\n\n*** ERROR *** Can't open mathffp.library: vector = %lx\n", MathBase);
exit();
}
else {
printf("\n\nSuccessfully opened mathffp.library: vector = %lx\n", MathBase);
}
if((MathTransBase = OpenLibrary("mathtrans.library", 0)) < 1 ) {
printf("\n\n*** ERROR *** Can't open mathtrans.library: vector = %lx\n", MathTransBase);
CloseLibrary(MathBase);
exit();
}
else {
printf("\n\nSuccessfully opened mathtrans.library: vector = %lx\n", MathTransBase);
}
/*****************************************/
/*****************************************/
/*** ***/
/*** COMPILER & FFP S.P. ADDITION ***/
/*** ***/
/*****************************************/
/*****************************************/
k1.num1 = PI; /* V1.0 Lattice C BUG! Can't have two */
k2.num2 = k1.num1 - PIME; /* constant assignments in a row. Fake */
/* it by making the second be an */
/* expression! */
printf("\n\n50,000 additions of %s to %s (Compiler Interface)\n", st1, st2);
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k3.num3 = k1.num1 + k2.num2;
show_dot();
}
show_result( k3.num3 );
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
printf("\n\n50,000 additions of %s to %s (Function Interface)\n", st1, st2 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k3.i3 = SPAdd(k2.i2, k1.i1);
show_dot();
}
show_result_ffp( k3.i3 );
/*****************************************/
/*****************************************/
/*** ***/
/*** COMPILER & FFP S.P. SUBTRACTION ***/
/*** ***/
/*****************************************/
/*****************************************/
k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n50,000 subtractions of %s from %s (Compiler Interface)\n", st1, st2 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k3.num3 = k2.num2 - k1.num1;
show_dot();
}
show_result( k3.num3 );
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
printf("\n\n50,000 subtractions of %s from %s (Function Interface)\n", st1, st2 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k3.i3 = SPSub(k1.i1, k2.i2);
show_dot();
}
show_result_ffp( k3.i3 );
/*****************************************/
/*****************************************/
/*** ***/
/*** COMPILER & FFP S.P. MULTIPLYS ***/
/*** ***/
/*****************************************/
/*****************************************/
k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n50,000 multiplies of %s by %s (Compiler Interface)\n", st1, st2 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k3.num3 = k1.num1 * k2.num2;
show_dot();
}
show_result( k3.num3 );
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
printf("\n\n50,000 multiplies of %s by %s (Function Interface)\n", st1, st2 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k3.i3 = SPMul(k2.i2, k1.i1);
show_dot();
}
show_result_ffp( k3.i3 );
/*****************************************/
/*****************************************/
/*** ***/
/*** COMPILER & FFP S.P. DIVISION ***/
/*** ***/
/*****************************************/
/*****************************************/
k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n50,000 divides of %s by %s (Compiler Interface)\n", st1, st2 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k3.num3 = k1.num1 / k2.num2;
show_dot();
}
show_result( k3.num3 );
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
printf("\n\n50,000 divides of %s by %s (Function Interface)\n", st1, st2 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k3.i3 = SPDiv(k2.i2, k1.i1);
show_dot();
}
show_result_ffp( k3.i3 );
/*****************************************/
/*****************************************/
/*** ***/
/*** COMPILER & FFP S.P. TRUNCATION ***/
/*** ***/
/*****************************************/
/*****************************************/
k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n50,000 fixes of %s (Compiler Interface)\n", st1 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
i3 = (int) k1.num1;
if( ++dots_good == 1000) { dots_good = 0; printf(".");}
}
printf("\nResult = %d", i3 );
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
printf("\n\n50,000 fixes of %s (Function Interface)\n", st1 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
i3 = SPFix(k1.i1);
if( ++dots_good == 1000) { dots_good = 0; printf(".");}
}
printf("\nResult = %d", i3);
/*****************************************/
/*****************************************/
/*** ***/
/*** COMPILER & FFP S.P. FLOATATION ***/
/*** ***/
/*****************************************/
/*****************************************/
i3 = 5;
printf("\n\n50,000 floats of %d (Compiler Interface)\n", i3 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k4.num4 = (FLOAT) i3;
show_dot();
}
show_result( k4.num4 );
printf("\n\n50,000 floats of %d (Function Interface)\n", i3 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k4.i4 = SPFlt(i3);
show_dot();
}
show_result_ffp( k4.i4 );
/*****************************************/
/*****************************************/
/*** ***/
/*** COMPILER & FFP S.P. NEGATION ***/
/*** ***/
/*****************************************/
/*****************************************/
k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n50,000 negates of %s (Compiler Interface)\n", st2 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k4.num4 = -k2.num2;
show_dot();
}
show_result( k4.num4 );
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
printf("\n\n50,000 negates of %s (Function Interface)\n", st2 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k4.i4 = SPNeg(k2.i2);
show_dot();
}
show_result_ffp( k4.i4 );
/*****************************************/
/*****************************************/
/*** ***/
/*** COMPILER & FFP S.P. ABSOLUTE VAL ***/
/*** ***/
/*****************************************/
/*****************************************/
k1.num1 = PI;
k4.num4 = PIME - k1.num1;
printf("\n\n50,000 absolute values of %f (Compiler Interface)\n", k4.num4 );
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k5.num5 = fabs(k4.num4);
show_dot();
}
show_result( k5.num5 );
printf("\n\n50,000 absolute values of %f (Function Interface)\n", k4.num4 );
k4.i4 = SPFieee(k4.i4);
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k5.i5 = SPAbs(k4.i4);
show_dot();
}
show_result_ffp( k5.i5 );
printf("\n\n*** HIT RETURN TO CONTINUE ***"); getch();
/*****************************************/
/*****************************************/
/*** ***/
/*** COMPILER & FFP S.P. COMPARE ***/
/*** ***/
/*****************************************/
/*****************************************/
k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
if (k2.num2 >= k1.num1)
printf("\n\n%f is greater than or equal to %f (Compiler Interface)\n", k2.num2, k1.num1);
else
printf("\n\n%f is less than %f (Compiler Interface)\n", k2.num2, k1.num1);
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
printf("\n*** SPCmp(k2.i2, k1.i1) returned %d ***", SPCmp(k2.i2, k1.i1));
if (SPCmp(k2.i2, k1.i1)) /* V1.0 FFP Bug. SPCmp() broken. */
{ k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n%f is greater than or equal to %f (Function Interface)\n", k2.num2, k1.num1);
}
else
{ k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n%f is less than %f (Function Interface)\n", k2.num2, k1.num1);
}
if (k1.num1 >= k2.num2)
printf("\n\n%f is greater than or equal to %f (Compiler Interface)\n", k1.num1, k2.num2);
else
printf("\n\n%f is less than %f (Compiler Interface)\n", k1.num1, k2.num2);
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
if (SPCmp(k1.i1, k2.i2))
{ k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n%f is greater than or equal to %f (Function Interface)\n", k1.num1, k2.num2);
}
else
{ k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n%f is less than %f (Function Interface)\n", k1.num1, k2.num2);
}
/*****************************************/
/*****************************************/
/*** ***/
/*** COMPILER & FFP S.P. TEST ***/
/*** ***/
/*****************************************/
/*****************************************/
if (k2.num2)
printf("\n\n%f is not equal to 0.0 (Compiler Interface)\n", k2.num2);
else
printf("\n\n%f is equal to 0.0 (Compiler Interface)\n", k2.num2);
k2.i2 = SPFieee(k2.i2);
if (SPTst(k2.i2))
{ k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n%f is not equal to 0.0 (Function Interface)\n", k2.num2);
}
else
{ k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n%f is equal to 0.0 (Function Interface)\n", k2.num2);
}
k2.num2 = 0.0;
if (k2.num2)
printf("\n\n%f is not equal to 0.0 (Compiler Interface)\n", k2.num2);
else
printf("\n\n%f is equal to 0.0 (Compiler Interface)\n", k2.num2);
k2.i2 = SPFieee(k2.i2);
if (SPTst(k2.i2))
{ k2.num2 = 0.0;
printf("\n\n%f is not equal to 0.0 (Function Interface)\n", k2.i2);
}
else
{ k2.num2 = 0.0;
printf("\n\n%f is equal to 0.0 (Function Interface)\n", k2.i2);
}
/*****************************************/
/*****************************************/
/*** ***/
/*** FFP S.P. SQUARE ROOT ***/
/*** ***/
/*****************************************/
/*****************************************/
k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
printf("\n\n50,000 square roots of %f\n", k2.num2);
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
for( dots_good = 0, i= 1; i < 50000; i++ )
{
k3.i3 = SPSqrt( k2.i2 );
show_dot();
}
show_result_ffp( k3.i3 );
/*****************************************/
/*****************************************/
/*** ***/
/*** FFP S.P. NATURAL LOGARITHM ***/
/*** ***/
/*****************************************/
/*****************************************/
printf("\n\n40,000 logarithms of %s\n", st1 );
for( dots_good = 0, i= 1; i < 40000; i++ )
{
k3.i3 = SPLog( k1.i1 );
show_dot();
}
show_result_ffp( k3.i3 );
/*****************************************/
/*****************************************/
/*** ***/
/*** FFP S.P. EXPONENT (BASE e) ***/
/*** ***/
/*****************************************/
/*****************************************/
printf("\n\n40,000 exponents of %s\n", st1 );
for( dots_good = 0, i= 1; i < 40000; i++ )
{
k3.i3 = SPExp( k1.i1 );
show_dot();
}
show_result_ffp( k3.i3 );
/*****************************************/
/*****************************************/
/*** ***/
/*** FFP S.P. SINE, COSINE & TANGENT ***/
/*** ***/
/*****************************************/
/*****************************************/
k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
k1.num1 = k1.num1 / 6.0;
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
printf("\n\n20,000 sines, cosines and tangents of %s / 6 radians\n", st1 );
for( dots_good = 0, i= 1; i < 20000; i++ )
{
k2.i2 = SPSin(k1.i1);
k3.i3 = SPCos(k1.i1);
k4.i4 = SPTan(k1.i1);
k5.i5 = SPSincos(&k6.i6, k1.i1); /* V1.0 FFP BUG! Cosine return */
/* value (k6.i6) of SPSincos is */
/* broken. Function result */
/* (sine -- k5.i5) is OK. */
show_dot();
}
show_result_ffp( k2.i2 ); show_result_ffp( k3.i3 );
show_result_ffp( k4.i4 );
show_result_ffp( k5.i5 ); show_result_ffp( k6.i6 );
/*****************************************/
/*****************************************/
/*** ***/
/*** FFP S.P. ARCTANGENT ***/
/*** ***/
/*****************************************/
/*****************************************/
printf("\n\n20,000 arctangents of the tangent of %s / 6 radians\n", st1 );
for( dots_good = 0, i= 1; i < 20000; i++ )
{
k2.i2 = SPAtan(k4.i4);
show_dot();
}
show_result_ffp( k2.i2 );
/***************************************************/
/***************************************************/
/*** ***/
/*** FFP S.P. HYPERBOLIC SINE, COSINE & TANGENT ***/
/*** ***/
/***************************************************/
/***************************************************/
k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
printf("\n\n20,000 hyperbolic sines, cosines and tangents of %s radians\n", st1 );
for( dots_good = 0, i= 1; i < 20000; i++ )
{
k2.i2 = SPSinh( k1.i1 );
k3.i3 = SPCosh( k1.i1 );
k4.i4 = SPTanh( k1.i1 );
show_dot();
}
show_result_ffp( k2.i2 ); show_result_ffp( k3.i3 ); show_result_ffp( k4.i4 );
/*****************************************/
/*****************************************/
/*** ***/
/*** FFP S.P. POWER FUNCTION ***/
/*** ***/
/*****************************************/
/*****************************************/
k1.num1 = PI;
k2.num2 = k1.num1 - PIME;
k1.i1 = SPFieee(k1.i1);
k2.i2 = SPFieee(k2.i2);
printf("\n\n10,000 %s raised to the %s power\n", st1, st2 );
for( dots_good = 0, i= 1; i < 10000; i++ )
{
k3.i3 = SPPow( k2.i2, k1.i1 );
show_dot();
}
show_result_ffp( k3.i3 );
/*****************************************/
/*****************************************/
/*** ***/
/*** CLOSE ROM AND RAM FFP LIBRARIES ***/
/*** ***/
/*****************************************/
/*****************************************/
RemLibrary(MathTransBase); /* Mark lib for Expunge() from RAM upon */
/* CloseLibrary() by last opener. Else */
/* lib stays in RAM for others to use */
/* quickly (no need to go to disk) until */
/* AllocMem() finds it needs the memory */
/* for some other purpose. */
CloseLibrary(MathTransBase); /* Close transcendental math RAM library */
CloseLibrary(MathBase); /* Close basic math ROM library */
printf("\n\nEnd C-ROM & Shared RAM Library Test (LATTICE) \n");
}